﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Mime;
using System.Net.NetworkInformation;
using System.Security.Authentication;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JkUtils
{
    public class JkNet
    {
        //端口是否被占用
        public static bool IsPortInUse(int port,string portType = "tcp")
        {
            IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            IPEndPoint[] ipEndPoints = portType == "tcp"?ipProperties.GetActiveTcpListeners():ipProperties.GetActiveUdpListeners();
            bool isUsed = false;
            foreach (IPEndPoint ipEndPoint in ipEndPoints)
            {
                if (ipEndPoint.Port == port)
                {
                    isUsed = true;
                    break;
                }
            }
            return isUsed;
        }
        // 简单缓存，避免频繁请求
        private static string _cachedIp;
        private static DateTime _cachedTime;
        private static readonly TimeSpan CacheTtl = TimeSpan.FromMinutes(5);
        private static readonly string[] Endpoints =
        {
            "https://api.ipify.org",
            "https://ifconfig.me/ip",
            "https://ipv4.icanhazip.com",
            "https://checkip.amazonaws.com"
        };

        public static async Task<string> Request(string url,  CancellationToken cancellationToken = default,string proxy = "",bool isClick = false,string Cookie="",bool isPost = false)
        {
            string result = string.Empty;
            var handler = new HttpClientHandler { 
                AllowAutoRedirect = true
            };

            if (proxy.JkNotNullOrWhiteSpace())
            {
                handler.UseProxy = true;
                IWebProxy webProxy = new WebProxy(proxy);
                handler.Proxy = webProxy;
            }
            string cookie = "";
            using (HttpClient client = new HttpClient(handler))
            {
                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36");
                client.DefaultRequestHeaders.Add("accept", "*/*");
                if (isClick)
                {
                    client.DefaultRequestHeaders.Add("origin", "http://touch.dujia.qunar.com");
                    client.DefaultRequestHeaders.Add("referer", "http://touch.dujia.qunar.com");
                    client.DefaultRequestHeaders.TryGetValues("Cookie", out _);
                    client.DefaultRequestHeaders.Remove("Cookie");
                    client.DefaultRequestHeaders.Add("Cookie", Cookie);
                }
                HttpResponseMessage response;
                if (isPost)
                {
                    StringContent content = new StringContent("");
                    response = await client.PostAsync(url, content, cancellationToken);
                } else
                {
                    response = await client.GetAsync(url, cancellationToken);
                }
                
                response.EnsureSuccessStatusCode();
                if (isClick)
                {
                    cookie = response.Headers.GetValues("Set-Cookie").FirstOrDefault();
                } else
                {
                    result = await response.Content.ReadAsStringAsync();
                }
               
            }
            handler.Dispose();
            return isClick?  cookie: result;
        }

        public static async Task<string> PostRequest(string url, string data)
        {
            string result = "";
            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
                StringContent content = new StringContent(data, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PostAsync(url, content);
                if (response.IsSuccessStatusCode)
                {
                    result = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(result);
                    await Task.Delay(1000);
                }
                else
                {
                    Console.WriteLine("请求失败：" + response.StatusCode);
                }
            }
            return result;
        }
        /// <summary>
        /// 获取本机公网 IPv4（多端点轮询，成功即返回）
        /// </summary>
        public static async Task<string> GetPublicIpAsync(CancellationToken token = default)
        {
            if (!string.IsNullOrEmpty(_cachedIp) && DateTime.UtcNow - _cachedTime < CacheTtl)
                return _cachedIp;

            foreach (var url in Endpoints)
            {
                try
                {
                    using (var cts = CancellationTokenSource.CreateLinkedTokenSource(token))
                    {
                        cts.CancelAfter(4000); // 每个端点超时 4s
                        using (var http = new HttpClient())
                        {
                            http.Timeout = TimeSpan.FromSeconds(4);
                            var resp = await http.GetAsync(url, cts.Token).ConfigureAwait(false);
                            if (!resp.IsSuccessStatusCode) continue;
                            var text = (await resp.Content.ReadAsStringAsync().ConfigureAwait(false)).Trim();
                            if (IsValidIPv4(text))
                            {
                                _cachedIp = text;
                                _cachedTime = DateTime.UtcNow;
                                return text;
                            }
                        }
                    }
                }
                catch
                {
                    // 忽略，尝试下一个
                }
            }
            return null;
        }

        private static bool IsValidIPv4(string ip)
        {
            if (string.IsNullOrWhiteSpace(ip)) return false;
            var parts = ip.Split('.');
            if (parts.Length != 4) return false;
            foreach (var p in parts)
            {
                if (!int.TryParse(p, out int v)) return false;
                if (v < 0 || v > 255) return false;
            }
            return true;
        }



    }
}
